#import "ALEventViewController.h"
#import "ALEventColumnView.h"
#import <SMRColumnView/SMRColumnEntry.h>
#import "NSManagedObject+SMRAdditions.h"
#import "NSManagedObjectContext+SMRAdditions.h"
#import "NSAttributedString+SMRAdditions.h"
#import "NSObject+BlockObservation.h"
#import "ALMainWindowController.h"
#import "ALElementColumnEntry.h"
#import "ALElement.h"
#import "ALElementTemplate.h"
#import "ALEntry+DisplayAdditions.h"
#import "SMROverlayShadowEffectView.h"
#import "ALDetailViewController.h"


#pragma mark Constants
static NSString* const ALEventViewControllerLabelAscendingSortKey = @"labelAscendingSortDescriptors";
static NSString* const ALEventViewControllerLineNumberAscendingSortKey = @"lineNumberAscendingSortDescriptors";


#pragma mark -
@interface ALEventViewController()
-(void)setupPrototypeLabels_;
-(ALDetailViewController *)detailViewController;
@end


#pragma mark -
@implementation ALEventViewController

@synthesize entriesArrayController;
@synthesize versionPrototype;


#pragma mark -
#pragma mark Initialization

-(void)awakeFromNib {
    [self setupPrototypeLabels_];
    NSColor *backColor = [NSColor colorWithCalibratedWhite:0.606 alpha:1.000];
    [[self eventColumnView] setBackgroundColor:backColor];
    
    NSArray *sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"versionNumber" ascending:YES]];
    [[self eventColumnView] setChildEntriesSortDescriptors:sortDescriptors];
    NSString *contentKeyPath = [NSString stringWithFormat:@"arrangedObjects.@distinctUnionOfObjects.version"];
    [[self eventColumnView] bind:SMRColumnViewContentBinding toObject:[self entriesArrayController] withKeyPath:contentKeyPath options:nil];
    [[self versionPrototype] setChildEntriesBindingKeypath:ALEntriesKey];
    [[self entryPrototype] bind:SMRColumnViewSortDescriptorsBinding toObject:self withKeyPath:ALEventViewControllerLineNumberAscendingSortKey options:nil];
        
	NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter];
	[noteCenter addObserver:self selector:@selector(entriesWereAdded:) name:ALEntriesWereAddedNotification object:nil];
    [noteCenter addObserver:self selector:@selector(filterScopeBarSelectionDidChange:) name:SMRScopeBarSelectionDidChangeNotification object:nil];
    [noteCenter addObserver:self selector:@selector(customFilterSelectionDidChange:) name:ALCustomEntryFilterDidChangeNotification object:nil];
}

-(void)setupPrototypeLabels_ {
    NSColor *labelNormalPrimaryColor = [NSColor colorWithCalibratedWhite:0.55f alpha:1.0f];
    NSColor *labelNormalSecondaryColor = [NSColor colorWithCalibratedWhite:0.6f alpha:1.0f];
    NSColor *labelHighlightedPrimaryColor = [NSColor colorWithCalibratedWhite:0.25f alpha:1.0f];
    NSColor *labelHighlightedSecondaryColor = [NSColor colorWithCalibratedWhite:0.2f alpha:1.0f];
    NSColor *valueColor = [NSColor blackColor];
    NSArray *prototypes = [NSArray arrayWithObjects:[self textElementPrototype], [self wrappingTextElementPrototype], [self dateElementPrototype], [self ratingElementPrototype], [self attachmentElementPrototype], nil];
    for (ALElementColumnEntry *prototype in prototypes) {
        [prototype setLabelNormalPrimaryColor:labelNormalPrimaryColor];
        [prototype setLabelNormalSecondaryColor:labelNormalSecondaryColor];
        [prototype setLabelHighlightedPrimaryColor:labelHighlightedPrimaryColor];
        [prototype setLabelHighlightedSecondaryColor:labelHighlightedSecondaryColor];
        [prototype setValueNormalPrimaryColor:valueColor];
        [prototype setValueNormalSecondaryColor:valueColor];
        [prototype setValueHighlightedPrimaryColor:valueColor];
        [prototype setValueHighlightedSecondaryColor:valueColor];
    }
}


#pragma mark -
#pragma mark Accessors

-(ALDetailViewController *)detailViewController {
    return (ALDetailViewController *)[self parent];
}

-(NSArray *)labelAscendingSortDescriptors {
	return [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:ALLabelKey ascending:YES]];
}

-(NSArray *)lineNumberAscendingSortDescriptors {
	return [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:ALLineNumberKey ascending:YES]];
}


#pragma mark -
#pragma mark Notifications

-(void)entriesWereAdded:(NSNotification *)note {
	NSArray *addedEntries = [note object];
	if (!addedEntries || [addedEntries count] == 0)
		return;
	NSMutableArray *addedColumnEntries = [NSMutableArray arrayWithCapacity:[addedEntries count]];
	for (id entry in addedEntries) {
		SMRColumnEntry *addedColumnEntry = [[self eventColumnView] entryWithRepresentedObject:entry];
		NSAssert(addedColumnEntry != nil, @"ALEventViewController:entriesWereAdded: added entry not member of column view");
		[addedColumnEntries addObject:addedColumnEntry];
	}
	[[self eventColumnView] selectEntries:addedColumnEntries extendSelection:NO];
	[[[self eventColumnView] window] makeFirstResponder:[self eventColumnView]];
}

-(void)filterScopeBarSelectionDidChange:(NSNotification *)note {
    // TODO: RE-CODE TO SUPPORT TAGS VICE sectionS
//    SMRScopeBarGroup *changedGroup = [note object];
//    if ([[changedGroup selectionIndexes] count] == 0)  // Group deselected
//        return;
//    NSString *groupIdentifier = [changedGroup identifier];
//    if ([groupIdentifier isEqualToString:kALDetailToolbarCustomGroupIdentifier])
//        return;
//    [[self sectionPrototype] setChildEntriesFilterPredicate:nil];
//    if ([groupIdentifier isEqualToString:kALDetailToolbarAllGroupIdentifier]) {
//        [[self eventColumnView] setChildEntriesFilterPredicate:nil];
//        return;
//    }
//    if (![groupIdentifier isEqualToString:kALDetailToolbarTagGroupIdentifier]) 
//        return;
//    ALsection *selectedsectionTemplate = [changedGroup selectedObject];
//    [[self eventColumnView] setChildEntriesFilterPredicate:[NSPredicate predicateWithFormat:@"template == %@", selectedsectionTemplate]];
}

-(void)customFilterSelectionDidChange:(NSNotification *)note {
    // TODO: RE-CODE TO HANDLE ENTRIES AND NOT SECTIONS
//    NSArray *selectedEntryTemplates = [note object];
//    NSArray *sectionTemplates = [selectedEntryTemplates valueForKeyPath:@"@distinctUnionOfObjects.sectionTemplate"];
//    [[self eventColumnView] setChildEntriesFilterPredicate:[NSPredicate predicateWithFormat:@"template IN %@", sectionTemplates]];
}


#pragma mark -
#pragma mark Column view delegate methods

-(NSView *)columnView:(SMRColumnView *)aColumnView willForwardHitTestAtPoint:(NSPoint)aPoint toSubview:(NSView *)subview {
	SMRColumnEntry *hitEntry = [aColumnView entryWithView:subview];
//	if ([hitEntry isKindOfClass:[ALsectionColumnEntry class]] && [subview isKindOfClass:[NSButton class]]) 
//		return subview;
	/*else*/ if ([hitEntry isKindOfClass:[ALElementColumnEntry class]])
		return [(ALElementColumnEntry *)hitEntry willForwardHitTestAtPoint:aPoint toSubview:subview];
	return aColumnView;	
}

-(id)columnView:(SMRColumnView *)aColumnView persistentObjectForRepresentedObject:(id)representedObject {
	if (![representedObject isKindOfClass:[NSManagedObject class]])
		return nil;
	NSString *uriString = [[representedObject smrURIRepresentation] absoluteString];
	return uriString;
}

-(id)columnView:(SMRColumnView *)aColumnView representedObjectForPersistentObject:(id)persistentObject {
	if (![persistentObject isKindOfClass:[NSString class]])
		return nil;
	NSURL *uri = [NSURL URLWithString:persistentObject];
	NSManagedObject *representedObject = [[self managedObjectContext] smrObjectWithURI:uri];
	return representedObject;
}


#pragma mark -
#pragma mark Actions

-(IBAction)testAction:(id)sender {
	LogDebug(@"%@", [[[[self windowController] valueForKey:@"selectedAppController"] valueForKey:@"selection"] valueForKey:@"title"]);
}

-(IBAction)editEntryTemplate:(id)sender {
	SMRColumnEntry *selectedEntry = [[self eventColumnView] selectedEntry];
	ALEntryTemplate *selectedTemplate = [(ALEntry *)[selectedEntry representedObject] template];
	NSRect selectedEntryRect = [[self eventColumnView] rectForEntry:selectedEntry];
	selectedEntryRect = NSInsetRect(selectedEntryRect, 5.0f, 5.0f);
	ALMainWindowController *windowController = (ALMainWindowController *)[self windowController];
	[windowController displayTemplateEditorForObject:selectedTemplate inView:[self eventColumnView] withRect:selectedEntryRect];
}

-(BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem {
	if ([anItem action] != @selector(editEntryTemplate:))
		return YES;
	NSUInteger selectionCount = [[[self eventColumnView] selectedEntries] count];
	return selectionCount == 1;
}


#pragma mark -
#pragma mark Detail subview overrides

-(NSUInteger)selectedEntriesCount {
	return [[[self eventColumnView] selectedEntries] count];
}

-(id)selectedEntryAtIndex:(NSUInteger)selectionIndex {
	if (selectionIndex != 0)
		return nil;
	return [[self eventColumnView] selectedObject];
}

-(NSRect)rectForSelectedEntry:(id)selectedEntryObject {
	SMRColumnEntry *selectedEntry = [[self eventColumnView] entryWithRepresentedObject:selectedEntryObject];
	NSRect selectedRect = [[self eventColumnView] rectForEntry:selectedEntry];
	selectedRect = [[self view] convertRect:selectedRect fromView:[self eventColumnView]];
	return selectedRect;
}


#pragma mark -
#pragma mark Prototypes

// Each element type has a custom column entry that handles view formatting for that type
-(SMRColumnEntry *)columnEntryPrototypeForRepresentedObject:(id)representedObject {
	if (![representedObject isKindOfClass:[ALElement class]])
		return nil;
	SMRColumnEntry *entry = nil;
	switch ([[representedObject elementType] integerValue]) {
		case ALElementTypeDate:
			entry = [self dateElementPrototype];
			break;
		case ALElementTypeRating:
			entry = [self ratingElementPrototype];
			break;
		case ALElementTypeText:
			entry = [[[(ALElement *)representedObject template] textPropertyWrapping] boolValue] ? [self wrappingTextElementPrototype] : [self textElementPrototype];
			break;
		case ALElementTypeAttachment:
			entry = [self attachmentElementPrototype];
			break;
		default: 
			return nil;
	}
	return [entry copy];
}

@end
